package legumes.client.services;

import java.io.IOException;
import java.util.Collection;
import java.util.List;

import legumes.shared.domain.AdminException;
import legumes.shared.domain.Customer;
import legumes.shared.domain.CustomerDTO;
import legumes.shared.domain.CustomerRole;
import legumes.shared.domain.LatLng;
import legumes.shared.domain.LoginException;
import legumes.shared.domain.MailStallParserException;
import legumes.shared.domain.NewProductMarket;
import legumes.shared.domain.Order;
import legumes.shared.domain.Product;
import legumes.shared.domain.ProductCategory;
import legumes.shared.domain.ProductVariety;
import legumes.shared.domain.SellSession;
import legumes.shared.domain.SellSessionForCustomer;
import legumes.shared.domain.Stall;
import legumes.shared.domain.Store;
import legumes.shared.domain.StoreException;
import legumes.shared.domain.UnicityViolationException;

import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("LegumesServices")
public interface LegumesServices extends RemoteService {

	public Stall parseStallMail(String mailContent_)
			throws MailStallParserException;

	public boolean isStoreOpened();

	public void setStoreOpened(boolean b_);

	public String getMessageStore();

	public void setMessageStore(String message_);

	public Customer getCustomer(String name_);

	public List<Product> getProducts();

	public List<Long> getSellSessionsDate();

	String log(String login_, String password_) throws LoginException;

	public CustomerDTO whoAmI();

	public void unlog();

	public SellSession getSellSession(long date_);

	public long getOpenedSellSessionId();

	public SellSessionForCustomer getSellSessionForCustomer();

	/**
	 * 
	 * @param fromSellSessionId_
	 *            sell session id from which the stall is copied. No stall copy
	 *            if it is null.
	 * @return new sell session
	 */
	public SellSession newSellSession(Store store_, long fromSellSessionId_);

	/**
	 * 
	 * @param sellSessionId_
	 * @param order_
	 * @param merge_
	 *            if true merge this order with an eventual order already in
	 *            data base. If false, replace the old order.
	 * @return the same order if merge_ is false, the merged order else.
	 * @throws StoreException
	 *             if the store is closed
	 * @throws LoginException
	 *             if the user is not logged
	 */
	public Order save(long sellSessionId_, Order order_, boolean merge_)
			throws StoreException, LoginException;

	/**
	 * 
	 * @param sellSessionId_
	 * @return true if there is another order
	 */
	public boolean hasOrderConflict(long sellSessionId_, Order order_);

	public void save(Stall stall_);

	public List<CustomerDTO> getCustomers();

	public Customer addCustomer(Customer c_) throws UnicityViolationException;

	/**
	 * 
	 * @param customerId_
	 *            email
	 * @throws LoginException 
	 */
	public void removeCustomer(String customerId_) throws AdminException, LoginException;

	public Collection<Order> getOrders(long sellSessionId_);

	/**
	 * 
	 * @param sellSessionId_
	 * @return url of report
	 * @throws IOException
	 */
	public String generateOrdersReport(long sellSessionId_)
			throws ToExcellException;

	public void changePassword(String password_, String newPassword_)
			throws LoginException;

	public void setCustomerRole(String customerid_, CustomerRole role_);

	Customer getCustomer(long uuid_);

	Product[] getProductsStartingWith(String prefix);

	boolean validateNewProductMarket(NewProductMarket newProductMarket_);

	Product addNewProductMarket(NewProductMarket newProductMarket_);

	ProductVariety[] getProductVarities();

	ProductCategory[] getProductCategories();

	String resetPassword(String email);

	List<Store> getUserStores(String userId);

	boolean removeStore(Store store_);

	boolean isStoreNameExists(String storeName);

	Store addStore(Store storeToAdd);

	List<Store> getStores(LatLng northEastBound, LatLng southWestBound);

	void save(Store store);
}
